import java.awt.*;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.table.*;

import org.jfree.chart.*;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.event.*;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.*;

class DemoTableModel extends AbstractTableModel implements TableModel {

	private Object data[][];

	public int getColumnCount() {
		return 5;
	}

	public int getRowCount() {
		return data.length;
	}

	public Object getValueAt(int i, int j) {
		return data[i][j];
	}

	public void setValueAt(Object obj, int i, int j) {
		data[i][j] = obj;
		fireTableDataChanged();
	}

	public String getColumnName(int i) {
		switch (i) {
		case 0: // '\0'
			return "Species:";

		case 1: // '\001'
			return "Region Number:";

		case 2: // '\002'
			return "Number of reads:";

		case 3: // '\003'
			return "Start:";

		case 4: // '\004'
			return "End:";
		}
		return null;
	}

	public DemoTableModel(int i) {
		data = new Object[i][5];
	}
}

public class Graphics extends ApplicationFrame implements ChartChangeListener,
		ChartProgressListener {

	private ChartPanel chartPanel;
	private DemoTableModel model;
	ArrayList<Species> species;
	int numberOfSpecies;
	XYSeriesCollection xySeriesCollection;

	public Graphics(int numberOfSpecies, String title, ArrayList<Species> species) {
		super(title);
		this.setLayout(new BorderLayout());
		this.numberOfSpecies = numberOfSpecies;
		this.species = species;
		JPanel jpanel = new JPanel(new BorderLayout());
		JFreeChart jfreechart = createChart(createDataset());
		jfreechart.addChangeListener(this);
		jfreechart.addProgressListener(this);
		jfreechart.setBackgroundPaint(Color.white);
		XYPlot xyplot = (XYPlot) jfreechart.getPlot();
		xyplot.setOrientation(PlotOrientation.VERTICAL);
		xyplot.setBackgroundPaint(Color.lightGray);
		xyplot.setDomainGridlinePaint(Color.white);
		xyplot.setRangeGridlinePaint(Color.white);
		xyplot.setAxisOffset(new RectangleInsets(5D, 5D, 5D, 5D));
		xyplot.setDomainCrosshairVisible(true);
		xyplot.setDomainCrosshairLockedOnData(false);
		xyplot.setRangeCrosshairVisible(false);
		chartPanel = new ChartPanel(jfreechart);
		chartPanel.setPreferredSize(new Dimension(600, 270));
		chartPanel.setDomainZoomable(true);
		chartPanel.setRangeZoomable(true);
		javax.swing.border.CompoundBorder compoundborder = BorderFactory
				.createCompoundBorder(
						BorderFactory.createEmptyBorder(4, 4, 4, 4),
						BorderFactory.createEtchedBorder());
		chartPanel.setBorder(compoundborder);
		jpanel.add(chartPanel);
		JPanel jpanel1 = new JPanel(new BorderLayout());
		jpanel1.setPreferredSize(new Dimension(400, 120));
		jpanel1.setBorder(BorderFactory.createEmptyBorder(0, 4, 4, 4));
		model = new DemoTableModel(numberOfSpecies);
		System.out.println(numberOfSpecies);
		for (int i = 0; i < numberOfSpecies; i++) {
			xyplot = (XYPlot) jfreechart.getPlot();
			model.setValueAt("Species "+i , i, 0);
			model.setValueAt(new Double("0.00"), i, 1);
			model.setValueAt(new Double("0.00"), i, 2);
			model.setValueAt(new Double("0.00"), i, 3);
			model.setValueAt(new Double("0.00"), i, 4);
		}

		JTable jtable = new JTable(model);
		NumberCellRenderer numbercellrenderer = new NumberCellRenderer();
		jtable.getColumnModel().getColumn(1)
				.setCellRenderer(numbercellrenderer);
		jtable.getColumnModel().getColumn(2)
				.setCellRenderer(numbercellrenderer);
		jtable.getColumnModel().getColumn(3)
				.setCellRenderer(numbercellrenderer);
		jtable.getColumnModel().getColumn(4)
				.setCellRenderer(numbercellrenderer);
		jpanel1.add(new JScrollPane(jtable));
		jpanel.add(jpanel1, "South");
		add(jpanel);
		// setContentPane(this);
		this.pack();
		RefineryUtilities.centerFrameOnScreen(this);
		this.setVisible(true);
	}

	private JFreeChart createChart(XYDataset dataset) {
		// create the chart...
		JFreeChart chart = ChartFactory.createXYLineChart(

		"Region of Interest x Number of Reads ", // chart title
				"Region of Interest", // x axis label
				"Number of Reads", // y axis label
				dataset, // data
				PlotOrientation.VERTICAL, true, // include legend
				true, // tooltips
				false // urls
				);
		// NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART...
		chart.setBackgroundPaint(Color.white);
		// StandardLegend legend = (StandardLegend) chart.getLegend();
		// legend.setDisplaySeriesShapes(true);
		// get a reference to the plot for further customisation...
		XYPlot plot = chart.getXYPlot();
		plot.setBackgroundPaint(Color.lightGray);
		// plot.setAxisOffset(new Spacer(Spacer.ABSOLUTE, 5.0, 5.0, 5.0, 5.0));
		plot.setDomainGridlinePaint(Color.white);
		plot.setRangeGridlinePaint(Color.white);
		// StandardXYItemRenderer renderer = (StandardXYItemRenderer)
		// plot.getRenderer();
		// renderer.setPlotShapes(true);
		// renderer.setShapesFilled(true);
		// change the auto tick unit selection to integer units only...
		NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
		rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
		// OPTIONAL CUSTOMISATION COMPLETED.
		return chart;
	}

	private XYDataset createDataset() {

		XYSeriesCollection xySeriesCollection = new XYSeriesCollection();
		for (int i = 0; i < numberOfSpecies; i++) {
			XYSeries series = new XYSeries("Species " + i);
			Double[] numberOfReads = this.species.get(i).toArray(
					this.species.get(i).numberOfReadsForRegion);
			Double[] numberOfRegion = this.species.get(i).toArray(
					this.species.get(i).numberOfGenes);
			for (int j = 0; j < numberOfReads.length; j++) {
				series.add(numberOfRegion[j], numberOfReads[j]);
			}
			xySeriesCollection.addSeries(series);
		}
		this.xySeriesCollection = xySeriesCollection;
		return xySeriesCollection;

	}

	public void chartChanged(ChartChangeEvent chartchangeevent) {
		if (chartPanel != null) {
			JFreeChart jfreechart = chartPanel.getChart();
			if (jfreechart != null) {
				XYPlot xyplot = (XYPlot) jfreechart.getPlot();
				XYDataset xydataset = xyplot.getDataset();
				Comparable comparable = xydataset.getSeriesKey(0);
				double d = xyplot.getDomainCrosshairValue();
				model.setValueAt(comparable, 0, 0);
				for (int i = 0; i < numberOfSpecies; i++) {
					if (d < this.species.get(i).numberOfGenes.size()) {
						Double y = this.xySeriesCollection
								.getYValue(i, (int) d);
						int startPosicion = this.species.get(i)
								.getStartPosicion(((int) d));
						int endPosicion = this.species.get(i).getEndPosicion(
								((int) d));
						model.setValueAt((int)d, i, 1);
						model.setValueAt(y, i, 2);
						model.setValueAt(startPosicion, i, 3);
						model.setValueAt(endPosicion, i, 4);
					}

				}

			}
		}
	}

	public void chartProgress(ChartProgressEvent chartprogressevent) {
		if (chartprogressevent.getType() != 2)
			return;
		if (chartPanel != null) {
			JFreeChart jfreechart = chartPanel.getChart();
			if (jfreechart != null) {
				XYPlot xyplot = (XYPlot) jfreechart.getPlot();
				XYDataset xydataset = xyplot.getDataset();
				Comparable comparable = xydataset.getSeriesKey(0);
				double d = xyplot.getDomainCrosshairValue();
				model.setValueAt(comparable, 0, 0);
				long l = (long) d;
				model.setValueAt(new Long(l), 0, 1);
				for (int i = 0; i < numberOfSpecies; i++) {
					if (d < this.species.get(i).numberOfGenes.size()) {
						Double y = this.xySeriesCollection
								.getYValue(i, (int) d);
						int startPosicion = this.species.get(i)
								.getStartPosicion(((int) d));
						int endPosicion = this.species.get(i).getEndPosicion(
								((int) d));
						model.setValueAt((int)d, i, 1);
						model.setValueAt(y, i, 2);
						model.setValueAt(startPosicion, i, 3);
						model.setValueAt(endPosicion, i, 4);
					}
				}
			}

		}
	}
}
